package org.controller;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import org.domain.Customer;
import org.domain.Flight;
import org.domain.Report;
import org.domain.Reservation;

public class 
ReservationController {

	private ReservationSystem system;
	private ThirdPartPaymentSystem paymentSystem;
		

	//initializes the system with initial data
	public ReservationController(ReservationSystem reservationSystem, ThirdPartPaymentSystem paymentSystem) {
		this.system = reservationSystem;
		this.paymentSystem = paymentSystem;
		system.initialize();
	}


	//searches for flight with given information
	//if flight has empty seats then return flight object
	//else return null
	public Flight isFlightAvailable(String dateOfFlight, String flightDeparture, String flightDestination) {
		Flight flight = system.searchFlight(dateOfFlight, flightDeparture.toUpperCase(), flightDestination.toUpperCase());
		if( flight != null && flight.getNumberOfSeatsLeft()>0)
			return flight;
		else
			return null;
	}

	//persists customer in system
	public Customer saveCustomerData(String firstName, String lastName, String dob,
			String phNumber) {
		Customer customer = new Customer(firstName.toUpperCase(), lastName.toUpperCase(), dob, phNumber);
		system.persistCustomer(customer);
		return customer;
	}

	
	//creates a reservation with current day date
	//generate confirmation number for the reservation
	//persists it in the system
	public String makeReservation(Customer customer, Flight flight,
			boolean hasBag, boolean disabilityAssistanceNeeded) {
		SimpleDateFormat formatter = new SimpleDateFormat("MM/dd/yyyy");
		String date = formatter.format(new Date());
		Reservation reservation = new Reservation(customer, flight, hasBag, disabilityAssistanceNeeded, date);
		String confirmationNumber = reservation.complete(system.getCountOfReservationMade());
		system.persistReservation(reservation);
		return confirmationNumber;
	}


	//creates a report with the sales made today and prints it
	public void generateDailyReport() {
		SimpleDateFormat formatter = new SimpleDateFormat("MM/dd/yyyy");
		String date = formatter.format(new Date());
		Report report = new Report(date, system.getCountOfReservationMade(), system.getRevenueGeneratedToday());
		system.persistReport(report);
		report.print();
	}

	//validates if flight information is correct
	//passes only if date format is correct and date is within 30 days
	public boolean validateFlightInfo(String dateOfFlight, String flightDeparture,
			String flightDestination) {
		if(dateOfFlight == null || flightDeparture == null || flightDestination == null
				|| dateOfFlight.isEmpty() || flightDeparture.isEmpty() || flightDestination.isEmpty())
			return false;
		if(!dateOfFlight.matches("^([1-9]|0[1-9]|1[0-2])[/]([1-9]|0[1-9]|1[0-9]|2[0-9]|3[0-1])[/](1[9][0-9][0-9]|2[0][0-9][0-9])$")){
			System.out.println("Error. Date of Flight needs to be in mm/dd/yyyy format");
			return false;
		}
		if(!isFlightDateWithin30Days(dateOfFlight)){
			System.out.println("Error. Only flights within the next 30 days can be booked");
			return false;
		}
		return true;
		
	}

	//checks if flight is within 30 days
	private boolean isFlightDateWithin30Days(String dateOfFlight) {
		Calendar flightDate = Calendar.getInstance();
		flightDate.setTime(new Date(dateOfFlight));
		Calendar today = Calendar.getInstance();
		if((flightDate.getTimeInMillis() - today.getTimeInMillis()) > 0
				&& (flightDate.getTimeInMillis() - today.getTimeInMillis())/(24*60*60*1000) <=30) 
											//24*60*60*1000 is the number of million seconds in 1 day
			return true;					//returns true if difference between days is less than or equal to 30 days
		return false;
	}

	//validates if customer data is correct
	public boolean validateCustomerInfo(String firstName, String lastName,
			String dateOfBirth, String phoneNumber) {
		if(firstName == null || lastName == null || dateOfBirth == null || phoneNumber == null
				|| firstName.isEmpty() || lastName.isEmpty() || phoneNumber.isEmpty() || dateOfBirth.isEmpty())
			return false;
		Customer customer = new Customer(firstName, lastName, dateOfBirth, phoneNumber);
		return customer.isCustomerDataValid();
	}
	
	//calls the 3rd party payment system to make payment
	public boolean makePayment(String creditCardNumber, String cvv, String expiryDate, String billingZipCode) {
		if(creditCardNumber == null || cvv == null || expiryDate == null || billingZipCode == null
				|| creditCardNumber.isEmpty() || cvv.isEmpty() || expiryDate.isEmpty() || billingZipCode.isEmpty())
			return false;
		return paymentSystem.pay(creditCardNumber, cvv, expiryDate, billingZipCode);
	}


	public void viewPastReport(String dateOfReport) {
		Report report = system.searchReport(dateOfReport);
		if(report != null)
			report.print();
		else
			System.out.println("Error. No report for this date exists");

	}
}
